package com.abocode.happybean.copy;


import com.abocode.happybean.copy.support.MethodMapKey;
import com.esotericsoftware.reflectasm.MethodAccess;

import java.util.ArrayList;
import java.util.List;

/**
 * @author guanxf
 */
public abstract class BeanCopier {
    public static void copyProperties(Object source, Object target) {
        MethodAccess sourceMethodAccess = MethodMapKey.getMethodMap().get(source.getClass());
        if (sourceMethodAccess == null) {
            sourceMethodAccess=MethodAccess.get(source.getClass());
            MethodFactory.putSourceMethodMap(sourceMethodAccess,source);
        }
        MethodAccess targetMethodAccess = MethodMapKey.getMethodMap().get(target.getClass());
        if (targetMethodAccess == null) {
            targetMethodAccess=MethodAccess.get(target.getClass());
            MethodFactory.putTargetMethodMap(targetMethodAccess,target);
        }
        List<String> fieldList = MethodMapKey.getFieldMap().get(target.getClass());
        for (String field : fieldList) {
            StringBuffer getKey=new StringBuffer(target.getClass().getName()).append(MethodMapKey.POINT_GET).append(field);
            StringBuffer setKey=new StringBuffer(target.getClass().getName()).append(MethodMapKey.POINT_SET).append(field);
            Integer setIndex = MethodMapKey.getMethodIndexMap().get(setKey.toString());
            int getIndex = MethodMapKey.getMethodIndexMap().get(getKey.toString());
            StringBuffer getSourceKey=new StringBuffer(source.getClass().getName()).append(MethodMapKey.POINT_GET).append(field);
            Integer sourceSetIndex= MethodMapKey.getMethodIndexMap().get(getSourceKey.toString());
            if (!StringUtils.isEmpty(getKey.toString()) && sourceSetIndex!=null){
                if (setIndex != null ) {
                    if (targetMethodAccess.invoke(target, getIndex) instanceof  List){
                        targetMethodAccess.invoke(target, setIndex.intValue(),sourceMethodAccess.invoke(source, sourceSetIndex));
                    }
                    targetMethodAccess.invoke(target, setIndex.intValue(),sourceMethodAccess.invoke(source, sourceSetIndex));
                }
            }
        }
    }

    public static <S,T> List<T> copyListProperties(List<S> sources, Object target){
      List targets=new ArrayList<Object>();
       for (Object object:sources){
            copyProperties(object,target);
            targets.add(target);
       }
       return targets;
    }
}
